package sheep.view.Component;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import org.jdesktop.animation.timing.*;
import sheep.view.utils.swingx.DropShadowPanel;
 
//==========================================================================  
   
public class CoolButton extends JButton implements TimingTarget {
      
  private static boolean REPAINT_SHADOW = true;    
  private static final Color COLOR1 = new Color(91, 118, 173);//new Color(125, 161, 237);    
  private static final Color COLOR2 = new Color(237, 237, 237);//new Color(91, 118, 173);  
  private int style;   
  private float pct;  
  private boolean forward;  
  private Animator anim = new Animator (200, this);      
  private final MouseAdapter MLISTENER = new MouseAdapter() {  
    @Override        
    public void mouseEntered(MouseEvent me) {            
      anim.stop();            
      forward = true;            
      anim.start();}       
    @Override        
    public void mouseExited(MouseEvent me) {           
      anim.stop();           
      forward = false;          
      anim.start();}   
  };

  @Override    
  public void begin() {}
    
  @Override    
  public void end() {       
    if (forward) {            
      setForeground(Color.DARK_GRAY);           
      pct = 1.0f;        
    } else {           
      setForeground(COLOR2);            
      pct = 0.0f;        
    }        
    Container p = getParent();        
    if (p instanceof DropShadowPanel && REPAINT_SHADOW) {        
      ((DropShadowPanel)p).propertyChange(null);        
    } else {            
      repaint();        
    }    
  }
        
  public CoolButton(int style) {       
    super();        
    this.style = style;       
    setContentAreaFilled(false);       
    setBorderPainted(false);       
    setForeground(COLOR2);       
    addMouseListener(MLISTENER);       
    setFont(getFont().deriveFont(Font.BOLD));    
  }
    
  @Override   
  public void paintComponent(Graphics g) {       
    Graphics2D g2d = (Graphics2D)g.create();    
    int h = getHeight();       
    int w = getWidth();        
    float tran = 0.1f + pct * 0.9f;
               
    GradientPaint GP = new GradientPaint(0, 0, COLOR1, 0, h, COLOR2, true);       
    g2d.setPaint(GP);             
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);       
    GradientPaint p1;      
    GradientPaint p2;
               
    if (getModel().isPressed()) {           
      p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1, new Color(100, 100, 100));            
      p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3, new Color(255, 255, 255, 100));        
    } else {            
      p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1, new Color(0, 0, 0));            
      p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0, h - 3, new Color(0, 0, 0, 50));        
    }        
        
    if (style == 0) {
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));         
      RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1, h - 1, 20, 20);         
      Shape clip = g2d.getClip();          
      g2d.clip(r2d);          
      g2d.fillRect(0, 0, w, h);          
      g2d.setClip(clip);          
      g2d.setPaint(p1);        
      g2d.drawRoundRect(0, 0, w - 1, h - 1, 20, 20);         
      g2d.setPaint(p2);          
      g2d.drawRoundRect(1, 1, w - 3, h - 3, 18, 18);            
      g2d.dispose();      
    } else if (style == 1) {            
      RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1 , h - 1+ 20, 20, 20);            
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));           
      Shape clip = g2d.getClip();           
      g2d.clip(r2d);          
      g2d.fillRect(0, 0, w, h);           
      g2d.setClip(clip);           
      g2d.setPaint(p1);           
      g2d.drawRoundRect(0, 0, w - 1, h - 1+ 20, 20, 20);            
      g2d.setPaint(p2);            
      g2d.drawRoundRect(1, 1, w - 3 , h - 3+ 20, 18, 18);           
      g2d.setPaint(p1);          
      //g2d.drawLine(w - 1, 1, w - 1, h);          
      g2d.setPaint(p2);          
      //g2d.drawLine(w - 2, 2, w - 2, h );          
      g2d.dispose();      
    } else if (style == 2) {         
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));           
      g2d.fillRect(0, 0, w, h);          
      g2d.setPaint(p1);           
      g2d.drawRect(-5, 0, w - 1 + 10, h - 1);            
      g2d.setPaint(p2);         
      g2d.drawRect(-5, 1, w - 3 + 10, h - 3);          
      g2d.setPaint(p1);          
      g2d.drawLine(0, 0, 0, h);        
      g2d.drawLine(w - 1, 1, w - 1, h);         
      g2d.setPaint(p2);         
      g2d.drawLine(1, 2, 1, h);         
      g2d.drawLine(w - 2, 2, w - 2, h - 1);         
      g2d.dispose();       
    } else if (style == 3) {           
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));           
      RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, -20, w - 1 , h - 1+ 20, 20, 20);           
      Shape clip = g2d.getClip();            
      g2d.clip(r2d);            
      g2d.fillRect(0, 0, w, h);            
      g2d.setClip(clip);            
      g2d.setPaint(p1);           
      g2d.drawRoundRect( 0,-20, w - 1 , h - 1+ 20, 20, 20);           
      g2d.setPaint(p2);            
      g2d.drawRoundRect( 1,1 - 20, w - 3 , h - 3+20, 18, 18);           
      g2d.setPaint(p1);           
      //g2d.drawLine(0, 1, 0, h);           
      g2d.setPaint(p2);            
      //g2d.drawLine(1, 2, 1, h - 1);          
      g2d.dispose();
    }else if (style == 4) {           
      RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1 + 20, h - 1, 20, 20);            
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));           
      Shape clip = g2d.getClip();           
      g2d.clip(r2d);           
      g2d.fillRect(0, 0, w, h);          
      g2d.setClip(clip);           
      g2d.setPaint(p1);          
      g2d.drawRoundRect(0, 0, w - 1 + 20, h - 1, 20, 20);          
      g2d.setPaint(p2);          
      g2d.drawRoundRect(1, 1, w - 3 + 20, h - 3, 18, 18);          
      g2d.setPaint(p1);          
      g2d.drawLine(w - 1, 1, w - 1, h);           
      g2d.setPaint(p2);         
      g2d.drawLine(w - 2, 2, w - 2, h - 1);           
      g2d.dispose();        
    } else if (style == 5) {            
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));            
      g2d.fillRect(0, 0, w, h);            
      g2d.setPaint(p1);            
      g2d.drawRect(-5, 0, w - 1 + 10, h - 1);           
      g2d.setPaint(p2);            
      g2d.drawRect(-5, 1, w - 3 + 10, h - 3);            
      g2d.setPaint(p1);           
      g2d.drawLine(0, 0, 0, h);           
      g2d.drawLine(w - 1, 1, w - 1, h);          
      g2d.setPaint(p2);            
      g2d.drawLine(1, 2, 1, h);            
      g2d.drawLine(w - 2, 2, w - 2, h - 1);            
      g2d.dispose();        
    } else if (style == 6) {            
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));           
      RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(-20, 0, w - 1 + 20, h - 1, 20, 20);           
      Shape clip = g2d.getClip();          
      g2d.clip(r2d);           
      g2d.fillRect(0, 0, w, h);          
      g2d.setClip(clip);            
      g2d.setPaint(p1);            
      g2d.drawRoundRect(-20, 0, w - 1 + 20, h - 1, 20, 20);           
      g2d.setPaint(p2);            
      g2d.drawRoundRect(1 - 20, 1, w - 3 + 20, h - 3, 18, 18);            
      g2d.setPaint(p1);            
      g2d.drawLine(0, 1, 0, h);            
      g2d.setPaint(p2);           
      g2d.drawLine(1, 2, 1, h - 1);         
      g2d.dispose();    
    }               
    super.paintComponent(g);    
  }
  
  public void timingEvent(float fraction) {       
    if (forward) {           
      pct = fraction;           
      int r = COLOR2.getRed() + (int) ((Color.WHITE.getRed() - COLOR2.getRed()) * pct);            
      int g = COLOR2.getGreen() + (int) ((Color.WHITE.getGreen() - COLOR2.getGreen()) * pct);           
      int b = COLOR2.getBlue() + (int) ((Color.WHITE.getBlue() - COLOR2.getBlue()) * pct);           
      setForeground(new Color(r, g, b));        
    } else {            
      pct = 1.0f - fraction;            
      int r = COLOR2.getRed() + (int) ((Color.WHITE.getRed() - COLOR2.getRed()) * pct);            
      int g = COLOR2.getGreen() + (int) ((Color.WHITE.getGreen() - COLOR2.getGreen()) * pct);            
      int b = COLOR2.getBlue() + (int) ((Color.WHITE.getBlue() - COLOR2.getBlue()) * pct);            
      setForeground(new Color(r, g, b));        
    }       
    Container p = getParent();      
    if (p instanceof DropShadowPanel && REPAINT_SHADOW)           
      ((DropShadowPanel)p).propertyChange(null);
  }
  
  public void repeat() {}
}
